package com.cf.base.leak.observe;

import com.cf.base.leak.ObjectWatcher;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import static com.cf.base.leak.utils.Utils.findClass;

/**
 * @author yangji
 */
public class MvpLeak {

    @SuppressWarnings({"unchecked"})
    public static void install(ObjectWatcher watcher) {

        //没有找到 presenter
        if (findClass("com.cf.base.mvp.mvp") || findClass("com.cf.base.mvp.callback.PresenterLifecycleCallbacks")) {
            return;
        }

        try {
            Class mvpClass = Class.forName("com.cf.base.mvp.Mvp");
            Class presenterCallbackClass = Class.forName("com.cf.base.mvp.callback.PresenterLifecycleCallbacks");

            Object callback = Proxy.newProxyInstance(watcher.getClass().getClassLoader(), new Class[]{presenterCallbackClass}, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if (method.getDeclaringClass() == Object.class) {
                        return method.invoke(this, args);
                    }

                    if (!"onDestroy".equals(method.getName())) {
                        return null;
                    }
                    //需要 记录 presenter 是否内存泄漏
                    if (args != null && args.length == 1) {
                        watcher.addWatcher(args[0], 60 * 1000);
                    }
                    return null;
                }
            });

            Method method = mvpClass.getMethod("getInstance");
            Object object = method.invoke(null);

            Method mvpMethod = mvpClass.getMethod("registerPresenterLifecycleCallbacks", presenterCallbackClass);
            mvpMethod.setAccessible(true);
            mvpMethod.invoke(object, callback);

        } catch (Exception e) {
            e.printStackTrace();
        }


    }

}
